//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using OpenLS.Media;
using OpenLS.Spreadsheet.UI.Internals;
using OpenLS.UI;

namespace OpenLS.Spreadsheet.UI
{
    static class GridSelection
    {
        public static void EnableCommands (UIElement g)
        {
            SpreadsheetElement.AddSelectionChanged(g, onSelectionChanged);
        }

        private static void onSelectionChanged(object sender, RangeChangedEventArgs args)
        {
            if (args.NewRange == null)
                return;
            Worksheet worksheet = WorksheetHelper.GetWorksheet(sender);
            worksheet.Selection = args.NewRange;
            worksheet.ActiveCell = args.ActiveCell;
        }
    }
    static class GridMouseSelection
    {
        public static void EnableCommands(UIElement g)
        {
            g.MouseDown += gridMouseDown;
            g.MouseMove += gridMouseMove;
            g.MouseUp += gMouseUp;
            
        }

        static void gMouseUp(object sender, MouseButtonEventArgs e)
        {
            var worksheetGrid = (WorksheetGrid)sender;
            if (worksheetGrid.Cursor == OfficeCursors.PaintCell) //\\not great
            {
                worksheetGrid.Cursor = OfficeCursors.DefaultCell;
                GridClipboard.PasteFormats(worksheetGrid);
                SpreadsheetElement.ForgetHightlightForAndClipboardMonitor(sender);
            }

            if (Mouse.Captured == sender)
                Mouse.Capture(null);
        }

        static void gridMouseMove(object sender, MouseEventArgs e)
        {
            if (Mouse.Captured != null && Mouse.Captured != sender)
                return;
            if (Mouse.Captured == null)
                return;
            var worksheetGrid = (WorksheetGrid)sender;
            Worksheet worksheet = WorksheetHelper.GetWorksheet(sender);
            if (worksheet == null)
                return;
            var activeCell = SpreadsheetElement.GetWorkingActiveCell(sender);
            if (activeCell == null)
                return;
            if (e.LeftButton == MouseButtonState.Pressed && !DragDropManager.IsDragging)
            {
                var c1 = worksheetGrid.GetCellAddressFrom( e.GetPosition);
                EditedCell cell = EditionElement.GetEditedCell((DependencyObject) sender);
                if (cell != null && cell.Formula.ActiveReference != null)
                {
                    FormulaReference r = cell.Formula.ActiveReference;
                    if (r != null)
                    {
                        r.Extend(c1, ResizerType.BottomRight);
                        return;
                    }

                }
                var selection = SpreadsheetElement.GetWorkingSelection(sender);
                if (selection is CompositeRange)
                {
                    CompositeRange cr = (CompositeRange) selection;
                    selection = CellsRange.Create(worksheet,
                                            new RangeAddress(activeCell.Address, c1));
                    selection =
                        new CompositeRange(Enumerable.Union(Enumerable.Take(cr.Ranges, cr.Ranges.Count - 1),
                                                            new SimpleRange[] {(SimpleRange) selection}));
                }
                else
                {
                    selection = CellsRange.Create(worksheet,
                                                            new RangeAddress(activeCell.Address, c1));
                }
                if (!selection.Contains(activeCell))
                    activeCell = selection.FirstCell;
                SpreadsheetElement.SetCurrentRangeForRoot(sender, selection, activeCell);
                //worksheet.Selection = selection;
                WorksheetPane pane = (WorksheetPane) SpreadsheetElement.GetWorksheetPane((DependencyObject) sender);
                pane.EnsureVisible(c1);
                GridEditing.StopEditing(worksheetGrid, false); //\\ tocheck
            }
        }

        static void gridMouseDown(object sender, MouseButtonEventArgs e)
        {
            var worksheetGrid = (WorksheetGrid)sender;
            Worksheet worksheet = WorksheetHelper.GetWorksheet(sender);
            if (worksheet == null)
                return;
            WorksheetPane pane = (WorksheetPane) SpreadsheetElement.GetWorksheetPane((DependencyObject)sender);
            pane.Activate();
            CellAddress address = worksheetGrid.GetCellAddressFrom(e.GetPosition);
            var currentRange = SpreadsheetElement.GetWorkingSelection(sender);
            bool skip = e.ChangedButton == MouseButton.Right;
            if (skip)
            {
                skip = false;
                if (currentRange!= null)
                    skip = currentRange.Contains(address);
            }
            bool willCapture = false;
            if (!skip)
            {
                if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && worksheet.ActiveCell != null)
                {
                    SpreadsheetElement.SetCurrentRangeForRoot(sender,
                                                              CellsRange.Create(worksheet,
                                                                                new RangeAddress(
                                                                                    worksheet.ActiveCell.Address,
                                                                                    address)), worksheet.ActiveCell);
                   //\\ worksheet.Selection = 
                 //\\       CellsRange.Create(worksheet, new RangeAddress(worksheet.ActiveCell.Address, address));
                }
                else
                {
                    EditedCell c = EditionElement.GetEditedCell((DependencyObject)sender);//\\
                    if (c != null)
                    {
                        if (false && c.Mode == EditionMode.Edit)
                        {
                            GridEditing.StopEditing(worksheetGrid, false);
                            EditionElement.SetEditedCell(worksheetGrid, null);
                            worksheet[address].Select();
                            return;
                        }
                        if (c.AcceptsPoint)
                        {
                            if (e.ChangedButton == MouseButton.Right)
                                return;
                            c._wantsCapture = true;
                            c.Formula.ActivateCellReference(worksheet[address]);
                            return;
                        }
                    }
                    bool needsCommit = c != null; //\\ && (c.Mode == EditionMode.Enter || c.Mode == enter;
                    GridEditing.StopEditing(worksheetGrid, needsCommit);
                    if (needsCommit)
                    {
                        c.Commit(c.Text);
                    }
                    EditionElement.SetEditedCellFor(sender, null); //\\Worksheet.EditedCell = null;
                    var hasControl = (Keyboard.Modifiers & ModifierKeys.Control) != 0;
                    var cell = worksheet[address];
                    if (!hasControl)
                    {
                        SpreadsheetElement.SetCurrentRangeForRoot(sender, cell.ToRange(), cell);
                        //\\cell.Select();
                    }
                    else
                    {
                        SpreadsheetElement.SetCurrentRangeForRoot(sender, Range.Union(SpreadsheetElement.GetWorkingSelection(sender), cell.ToRange()),cell);
                        //  worksheet.ActiveCell = cell;
//                        worksheet.Selection = Range.Union(worksheet.Selection, cell.ToRange());
  //                      worksheet.ActiveCell = cell;
                    }
                    willCapture = true; 
                }
            }
            if (willCapture)
                Mouse.Capture(worksheetGrid);
            worksheetGrid.Focus();
            if (e.ChangedButton == MouseButton.Left)
            {
                Cell cell = worksheet.NonVolatileCells.GetItemIfAny(address);
                if (cell != null)
                {
                    Hyperlink l = cell.Hyperlink;
                    if (l != null)
                    {
                        Cell target = l.TargetCell;
                        if (target != null)
                            SpreadsheetCommands.MoveTo.Execute(target, worksheetGrid);
                        else
                        {
                            cell.Worksheet.Workbook.InvokeCellLinkNavigate(new LinkNavigateEventArgs(cell, l.ExternalUri));
                        }
                    }
                }
            }
            if (e.ChangedButton == MouseButton.Right)
            {
                var contextMenu = worksheetGrid.TryFindResource(SpreadsheetWindowComponents.WorksheetCellsContextMenuKey) as ContextMenu;
                if (contextMenu == null)
                    contextMenu = worksheetGrid.FindResource(SpreadsheetWindowComponents.DefaultWorksheetCellsContextMenuKey) as ContextMenu;
                contextMenu.PlacementTarget = worksheetGrid;
                contextMenu.IsOpen = true;
                e.Handled = true;
            }

        }
    }
}
